home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / HDX_BACK / HDX501 / SECT.C < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-09  |  23.8 KB  |  1,006 lines

  1. /* sect.c */
  2.  
  3. /* 
  4.  * Aug-23-88 jye. Change and add codes so that can be used for MS-DOS
  5.  * Dec-20-89 jye. Free a bug that HDX gives a error message when CD-ROM 
  6.  *                  is busy. 
  7.  */
  8.  
  9. #include "obdefs.h"
  10. #include "osbind.h"
  11. #include "mydefs.h"
  12. #include "part.h"
  13. #include "hdx.h"
  14. #include "addr.h"
  15. #include "myerror.h"
  16.  
  17. #define    ZBUFSIZ    0x4000        /* about 16k == 32 sectors */
  18. #define    ZCOUNT    (ZBUFSIZ/0x200)    /* ZCOUNT = 32 */
  19. #define MAXUNITS 16            /* max number of logical units */
  20.  
  21. #define PUNINFO struct _punifno
  22. PUNINFO {
  23.         WORD puns;    /* number of physical units */
  24.         BYTE pun[MAXUNITS];
  25.         LONG partition_start[MAXUNITS]; /* offset to partition on */
  26.                                         /* physical unit */
  27. };
  28. extern long ostack;        /* old stack pointer */
  29. extern UWORD errcode();        /* function to return error code */
  30. extern int yesscan;        /* the flag for the func. IBMGPART use */
  31. extern long sptrk;        /* the sector per track */
  32. extern int npart;        /* the number of partitions */
  33. extern int ext;            /* the index of extended partition */
  34. extern int extend;        /* the index of end extended partition */
  35. extern int showmany;    /* the flag for show the too many device alert box */
  36. extern char ttscsi;        /* the flag for SCSI if set */
  37. extern char spscsixst;    /* set for the sparrow scsi exist */
  38. extern int needscan;    /* TRUE: if it is the first time to scan the units */
  39. extern int athead;        /* the # of data heads on the AT drive */
  40. extern int atcyl;        /* the # of cylinders on the AT drive */
  41. extern int atspt;        /* the # of sectors per track on the AT drive */
  42. extern int noacsi;        /* set for no ACSI drive in the system */
  43. extern char slwacsi;    /* 1: set for slow acsi device */
  44. extern char *drvid[];    /* for the id of the devices */
  45. /*
  46.  * Logical-to-dev+partition mapping table.
  47.  */
  48. int nlogdevs;                /* # logical devices */
  49. LOGMAP logmap[EXTRALOGD];    /* logical dev map */
  50. int livedevs[MAXPHYSDEVS];    /* live devs flags; 1: device is alive */
  51. int idevs[16];                /* the devs have id flags; 1: device has id */
  52. int typedev = 0x0000;        /* if set, driver is a removable driver */
  53. int typedrv = 0x0000;        /* if set, driver is a SCSI driver */
  54. int atexst;                    /* AT drive exists */
  55. int slvexst;                /* AT slave drive exists */
  56. char useblit;                /* set for it is not the stbook drive */
  57.  
  58.  
  59. /*
  60.  * Rebuild logical-to-physical mapping
  61.  * by reading and interpreting the root
  62.  * blocks for all physical devs.
  63.  *
  64.  */
  65.  
  66. rescan(flag, fnp)
  67.  
  68. int flag;    /* 0: don't report medium change error; */
  69.             /* non-0: report medium change error; */
  70. int fnp;    /* 0: do zero & markbad; 1: do format & ship; 2: do part */
  71.  
  72. {
  73.     int dev, scan=0;
  74.     char buf[512];
  75.     char sendata[32];
  76.     int partno, ret, inqret, i;
  77.     PART *partinfo;
  78.     char mask = 0x80;    /* 7th bit is set on */
  79.     int setmask;
  80.     int maxloop;
  81.  
  82.     noacsi = 1;                /* assume there is no ACSI in the system */
  83.     ostack = Super(NULL);    /* set supervice mode */
  84.  
  85.     ttscsi = chkscsi();        /* check if SCSI exists */
  86.     spscsixst = chksp();    /* check if sparrow scsi exists */
  87.     delay();
  88.     if ((atexst = chkide()))    { /* AT drive exist */
  89.         if (stbook())    {
  90.             useblit = 0;
  91.         } else {
  92.             useblit = chkblit();
  93.         }
  94.         if ((ret = identify(16, buf)) == OK)    {
  95.             delay();
  96.             /* in byte 54 of the buf having the drive's id */
  97.             gdrvid(16, &buf[54], drvid[16]);
  98.             /* return the number of cylinder, head, spt */
  99.             gparmfc(&atcyl, &athead, &atspt, buf);
  100.         } else { 
  101.             delay();
  102.             Super(ostack);
  103.             ret = errcode(16);
  104.             if (tsterr(ret) != OK) 
  105.                 return ERROR;
  106.             return (-3);    /* don't have to show the alert box */
  107.         }
  108.     }
  109.     delay();
  110.     /*
  111.     if ((atexst) && (slvexst = slave()))    {  AT slave drive exist 
  112.         if ((ret = identify(17, buf)) == OK)    {
  113.             atscyl = getword(buf+2);
  114.             atshead = getword(buf+6);
  115.             atsspt = getword(buf+12);
  116.             delay();
  117.         } else { 
  118.             delay();
  119.             Super(ostack);
  120.             ret = errcode(17);
  121.             if (tsterr(ret) != OK) 
  122.                 return ERROR;
  123.             return (-3);    don't have to show the alert box
  124.         }
  125.     }
  126.     */
  127.     delay();
  128.     Super(ostack);
  129.     /* set the scent message box */
  130.     if ((needscan) && ((ttscsi)||(spscsixst)))
  131.         dsplymsg(scanmsg);
  132.  
  133.     /* disable all logical and physical devs */
  134.     for (dev = 0; dev < EXTRALOGD; ++dev)
  135.         logmap[dev].lm_physdev = -1;
  136.  
  137.     for (dev = 0; dev < MAXPHYSDEVS; ++dev)
  138.         livedevs[dev] = 0;
  139.  
  140.     /* set all devices have no id */
  141.     for(i=0; i < 16; i++)    {
  142.         idevs[i] = 0;
  143.     }
  144.  
  145.     /*
  146.      * Scan all physical devs
  147.      * and pick up partition structures.
  148.      */
  149.     nlogdevs = 0;
  150.     showmany = 0;
  151.     slwacsi = 0;
  152.     if (atexst)    {
  153.         maxloop = 18;
  154.         dev = 16;
  155.     } else if ((ttscsi)||(spscsixst))    {
  156.         maxloop = 16;
  157.         dev = 8;
  158.     } else {
  159.         maxloop = 8;
  160.         slwacsi = 1;
  161.         dev = 0;
  162.     }
  163. rerescan:
  164.     for (; dev < maxloop; ++dev)
  165.     {
  166.  
  167.         if (((dev == 16) && atexst) || ((dev == 17) && slvexst))    {
  168.             if ((ret = getroot(dev, buf, (SECTOR)0)) != 0)    {
  169.                 if (tsterr(ret) != OK)    
  170.                     err(rootread);
  171.                 slwacsi = 0;
  172.                 return(ERROR);
  173.             }
  174.             goto atst;    /* skip and do the at stuff only */
  175.         }
  176.         /* initialize the buffer */
  177.         for (i = 0; i < 32; i++)        {
  178.             sendata[i] = 0;
  179.         }
  180.  
  181.         /* check see the drive is a what kind of drive */
  182.            ostack = Super(NULL);
  183.            delay();
  184.         if ((inqret = inquiry(dev, (WORD)32, sendata)) != ERROR)    {
  185.             for (i=8; i < 32; i++)    {
  186.                 if (sendata[i])    {
  187.                     break;
  188.                 }
  189.             }
  190.             if (i < 32)    {    /* there are some date return */
  191.                 gdrvid(dev, &sendata[8], drvid[dev]);
  192.                 idevs[dev] = 1;
  193.             }
  194.         }
  195.            delay();
  196.            Super(ostack);
  197.         setmask = 0x0001;
  198.         if (inqret & 0x08)    { /* the device is busy */
  199.             continue;
  200.         }
  201.         /* ret not equal OK, it may be a regular hard drive */
  202.         if ((inqret == OK)||(inqret == 7)) { /*it is not a regular hard drive*/
  203.             if (sendata[0])      {    /* it is not a hard drive */
  204.                 continue;
  205.             } else if (sendata[1] & mask)    { /* it is a removable drive */
  206.                 ;            /* don't set the SCSI bit */
  207.             } else {
  208.                   /* it is a SCSI drive */
  209.                 /* set the relative bit, 1 is a SCSI, other is not */
  210.                 typedrv |= setmask << dev;
  211.             }
  212.         }
  213.         if ((ret = getroot(dev, buf, (SECTOR)0)) < 0) {
  214.             if (!fnp)  rangelog(dev);
  215.             continue;
  216.         } else {        /* ret >= 0 */
  217.             if (ret > 0) {
  218.                 if ((flag) && (tsterr(ret) == OK))    {    
  219.                 /* if non-0, report error if medium changed */
  220.                         erasemsg();
  221.                         slwacsi = 0;
  222.                          return ERROR;
  223.                 }
  224.                 if ((ret = getroot(dev, buf, (SECTOR)0))) {    /* try again */
  225.                     if (ret > 0 && flag && tsterr(ret) == OK)    {
  226.                         erasemsg();
  227.                         slwacsi = 0;
  228.                         return ERROR;
  229.                     } else if ((ret > 0) && (!flag))    {
  230.                         if (((inqret == OK)||(inqret == 7)) && 
  231.                                              (sendata[1] & mask))    { 
  232.                             /* it is a removable drive */
  233.                             /* but forget insert the cartridge */
  234.                             err(instdrv);
  235.                             /*
  236.                             erasemsg();
  237.                             */
  238.                             /* set the relative bit, 1 is a removable */
  239.                             typedev |= setmask << dev;
  240.                         }
  241.                         /*
  242.                         if (fnp == 1)    {  do format 
  243.                             livedevs[dev] = 1;
  244.                             if (dev < 8)  there is a ACSI in the system 
  245.                                 noacsi = 0;
  246.                             yesscan = 1;
  247.                         }
  248.                         */
  249.                     }
  250.                     if (!fnp)    {
  251.                         rangelog(dev);
  252.                     }
  253.                     continue;
  254.                 }
  255.             }
  256.             if ((inqret == OK)||(inqret == 7))     {  /* it is a SCSI drive */
  257.                 if (sendata[1] & mask)    { /* it is a removable drive */
  258.                     /* set the relative bit, 1 is a removable, other is not */
  259.                     typedev |= setmask << dev;
  260.                 }
  261.             }
  262.     atst:
  263.             if (dev < 8)    {    /* there is a ACSI drive in the system */
  264.                 noacsi = 0;
  265.             }
  266.             livedevs[dev] = 1;
  267.             yesscan = 1;
  268.             if (stgpart(dev, buf, (PART *)&partinfo) == ERROR)    {
  269.                 erasemsg();
  270.                 slwacsi = 0;
  271.                 return ERROR;
  272.             }
  273.             if (ext != NO_EXT)    {
  274.                 sortpart(partinfo,SCAN_BS); 
  275.             }
  276.         for (partno = 0; partno < npart; ++partno) {
  277.             if ((partinfo[partno].p_flg & P_EXISTS) &&
  278.                 (partinfo[partno].p_siz != (SECTOR)0) &&
  279.                 (((partinfo[partno].p_id[0] == 'G') &&
  280.                  (partinfo[partno].p_id[1] == 'E') &&
  281.                  (partinfo[partno].p_id[2] == 'M'))   ||
  282.                  ((partinfo[partno].p_id[0] == 'B') &&
  283.                  (partinfo[partno].p_id[1] == 'G') &&
  284.                  (partinfo[partno].p_id[2] == 'M'))))   
  285.             {
  286.                 if (nlogdevs > EXTRALOGD)    {
  287.                     continue;
  288.                 }
  289.                 logmap[nlogdevs].lm_physdev = dev;
  290.                 logmap[nlogdevs].lm_partno = partno;
  291.                 logmap[nlogdevs].lm_start =  partinfo[partno].p_st;
  292.                 logmap[nlogdevs].lm_siz =      partinfo[partno].p_siz;
  293.                 ++nlogdevs;
  294.                 if (nlogdevs == MAXLOGDEVS)         {
  295.                     showmany = 1;
  296.                 }
  297.             }
  298.         }
  299.     }
  300.     inipart(partinfo, npart);
  301.     if (partinfo > 0)    Mfree(partinfo);
  302.     }
  303.  
  304.     if ((maxloop > 16) && ((ttscsi)||(spscsixst)))    {
  305.         maxloop = 16;
  306.         dev = 8;
  307.         slwacsi = 0;
  308.         goto rerescan;
  309.     } else if (((maxloop > 16) && ((!ttscsi)&&(!spscsixst))) 
  310.                                || ((ttscsi)&&(maxloop>8)))    {
  311.         maxloop = 8;
  312.         dev = 0;
  313.         slwacsi = 1;
  314.         goto rerescan;
  315.     }
  316.     erasemsg();
  317.     slwacsi = 0;
  318.     return OK;
  319. }
  320.  
  321.  
  322.  
  323. /* get the indentification of drive */
  324.  
  325. gdrvid(indx, sptr, dptr)
  326. int indx;
  327. char *sptr;
  328. char *dptr;
  329. {
  330.  
  331.     int i, j=0;
  332.  
  333.     /* string in ptr is sperated by space */
  334.     for (i=0; i < 24; i++)    {
  335.         if ((*dptr++ = *sptr++) == 0x20)    {
  336.             j++;
  337.             if (j > 1)    {
  338.                 dptr--;
  339.             }
  340.         } else {
  341.             j = 0;
  342.         }
  343.     }
  344.     *(dptr-1) = 0;
  345.     /*
  346.     while ((*sptr != 0x20) && (*sptr))    {
  347.         *dptr++ = *sptr++;
  348.     }
  349.     *dptr++ = 0x20;
  350.     sptr = ptr+8;
  351.     while ((*sptr != 0x20) && (*sptr))    {
  352.         *dptr++ = *sptr++;
  353.     }
  354.     *dptr = 0;
  355.     */
  356. }
  357.  
  358.  
  359. /* rerange the partition informations. */
  360.  
  361.  sortpart(pinfo, type)
  362.  PART *pinfo;
  363.  int type;                /* USER_ED = 1: for user interface use */
  364.                          /* SCAN_BS = 0: for rescan() and laybs() use */
  365.  {
  366.      int i, j, k;
  367.     PART rpart[2];
  368.  
  369.     if (ext == NO_EXT) return OK;    /* don't need sort */
  370.     for (i = 0; i < 2; i++)    { /* initialize the temple space */
  371.         rpart[i].p_flg = 0L;
  372.         rpart[i].p_st = 0L;
  373.         rpart[i].p_siz = 0L;
  374.         for (k = 0; k < 3; k++)
  375.             rpart[i].p_id[k] = '0';
  376.     }
  377.     /* save the partitions that after the extened partitions */
  378.     for (i = ext+1, j=0; i < 4; i++, j++)        {
  379.         if (pinfo[i].p_flg & P_EXISTS)    {
  380.             rpart[j].p_flg = P_EXISTS;
  381.             rpart[j].p_st = pinfo[i].p_st;
  382.             rpart[j].p_siz = pinfo[i].p_siz;
  383.             for (k = 0; k < 3; k++)
  384.                 rpart[j].p_id[k] = pinfo[i].p_id[k];
  385.         } 
  386.     }
  387.     /* move the extened partition to the front */
  388.      for (i=4, j = ext; i < npart; i++, j++)    {
  389.         if (pinfo[i].p_flg & P_EXISTS)    {
  390.             pinfo[j].p_flg = P_EXISTS;
  391.             pinfo[j].p_st = (type)?(pinfo[i].p_st):(pinfo[i].p_st + ROOTSECT);
  392.             pinfo[j].p_siz = (type)?(pinfo[i].p_siz):(pinfo[i].p_siz-ROOTSECT);
  393.             for (k = 0; k < 3; k++)
  394.                 pinfo[j].p_id[k] = pinfo[i].p_id[k];
  395.         } else { j--;}    /* stay with that space */
  396.     }
  397.     /* copy the not extended partitions back after the extended partitions */
  398.      for (i=0; i < 2; i++, j++)    {
  399.         if (rpart[i].p_flg & P_EXISTS)    {
  400.             pinfo[j].p_flg = P_EXISTS;
  401.             pinfo[j].p_st = rpart[i].p_st;
  402.             pinfo[j].p_siz = rpart[i].p_siz;
  403.             for (k = 0; k < 3; k++)
  404.                 pinfo[j].p_id[k] = rpart[i].p_id[k];
  405.         } else {j--;}
  406.     }
  407.     for (i = j; i < npart; i++)    { /* set the rest to 0 */
  408.         pinfo[i].p_flg = 0L;
  409.         pinfo[i].p_st = 0L;
  410.         pinfo[i].p_siz = 0L;
  411.         for (k = 0; k < 3; k++)
  412.             pinfo[i].p_id[k] = '0';
  413.     }
  414. }
  415.  
  416.  
  417. /* 
  418.  * check to find out the exist of device
  419.  */
  420.  
  421. rangelog(dev)
  422.  
  423. int dev;
  424.  
  425. {
  426.     PUNINFO *divinfo;
  427.     int devnum;
  428.  
  429.     ostack = Super(NULL);
  430.     divinfo = ((PUNINFO *) *((long *)(0x516)));
  431.     for (devnum = 0; devnum < MAXUNITS; ++devnum)    {
  432.         if ((int)(divinfo->pun[devnum] & 0x07) == dev)    {
  433.             delay();
  434.             nlogdevs++;
  435.         }
  436.     }
  437.     Super(ostack);
  438. }
  439.  
  440. /*
  441.  * From a PHYSICAL device unit (0->7)
  442.  * and a partition number (0->3), figure
  443.  * out the LOGICAL disk number ('C'->'P').
  444.  *
  445.  * return the LOGICAL disk number or
  446.  * ERROR if the PHYSICAL device doesn't exist.
  447.  *
  448.  */
  449. phys2log(pdev, pno)
  450. int  pdev;    /* physical device unit */
  451. int  pno;    /* partition number (0 -> 3) */
  452. {
  453.     int logdev;        /* index to step through partitions of a phys unit */
  454.  
  455.     for (logdev = 0; logdev < EXTRALOGD; logdev++) {
  456.         if (logmap[logdev].lm_physdev == pdev &&
  457.             logmap[logdev].lm_partno == pno)
  458.             return ('C'+logdev);
  459.     }
  460.     return ERROR;
  461. }
  462.  
  463.  
  464. /*
  465.  * Map block on logical device to
  466.  * block on physical device;
  467.  * return ERROR if the logical device
  468.  * doesn't exist.
  469.  */
  470. log2phys(adev, ablk)
  471. int *adev;
  472. SECTOR *ablk;
  473. {
  474.     int dev;
  475.     char xbuf[256];
  476.     
  477.     dev = *adev;
  478.     if (dev >= 0 && dev <= 17)
  479.     return OK;
  480.  
  481.     dev = toupper(dev);
  482.     if (dev >= 'C' && dev <= 
  483.                 ('C'+EXTRALOGD)) /* from C to 't' are 50 logic device */
  484.     {
  485.     dev -= 'C';
  486.     *adev = logmap[dev].lm_physdev;
  487.     *ablk = logmap[dev].lm_start + *ablk;
  488.     return OK;
  489.     }
  490.  
  491.     return ERROR;
  492. }
  493.  
  494.  
  495.  
  496. /*
  497.  * Return physical starting block# of a partition
  498.  *
  499.  */
  500. SECTOR 
  501. logstart(ldev)
  502. int ldev;    /* logical device */
  503. {
  504.     ldev = toupper(ldev);
  505.     if (ldev >= 'C' && ldev <= 
  506.                 ('C'+EXTRALOGD)){/*from C to 't' are 50 logic device */
  507.         ldev -= 'C';
  508.         return (logmap[ldev].lm_start);
  509.     }
  510.     return ERROR;
  511. }
  512.  
  513.  
  514.  
  515. /*
  516.  * Return physical starting block# of a partition's data block.
  517.  *
  518.  */
  519. SECTOR 
  520. logend(ldev)
  521. int ldev;    /* logical device */
  522. {
  523.     ldev = toupper(ldev);
  524.     if (ldev >= 'C' && ldev <= 
  525.                 ('C'+EXTRALOGD)){/*from C to 't' are 50 logic device */
  526.         ldev -= 'C';
  527.         return (logmap[ldev].lm_start+logmap[ldev].lm_siz-1);
  528.     }
  529.     return ERROR;
  530. }
  531.  
  532.  
  533. #define    MFM 17        /* sectors per track for MFM */
  534. #define    RLL 26        /* sectors per track for RLL */
  535.  
  536.  
  537. /*
  538.  * Check if dev's root block is intact.
  539.  * Return number of sectors per track on disk.
  540.  *
  541.  */
  542. chkroot(dev, bs)
  543. int dev;
  544. char *bs;
  545. {
  546.     extern long get3bytes();
  547.     extern long get4bytes();
  548.     SETMODE *mb;
  549.     int i, ret, set, scsidrv, mask=0x0001;
  550.     int page=4, bsiz;
  551.     int head, spt;
  552.     SECTOR size, msiz, cyl;    /* size of media */
  553.     char buf[512], sendata[32];
  554.     long dmaptr, tmpptr;
  555.     char *dmahigh=0xffff8609,
  556.          *dmamid=0xffff860b,
  557.          *dmalow=0xffff860d;
  558.     
  559.     size = ((RSECT *)(bs + 0x200 - sizeof(RSECT)))->hd_siz;
  560.     
  561.     ret = OK;
  562.     if (dev == 16)    {        /* it is a IDE-AT drive */
  563.         msiz = (SECTOR)athead * (SECTOR)atcyl * (SECTOR)atspt;
  564.         if (size != msiz)
  565.             ret = ERROR;
  566.         return(ret);
  567.     } else if (dev > 7)    {    /* it is a scsi drive */
  568.         ostack = Super(NULL);
  569.         delay();
  570.         if ((ret = readcap(dev, 0, (long)0, sendata)) == OK) {
  571.             if (msiz = get4bytes(sendata))    {
  572.                 msiz += 1;
  573.                 delay();
  574.                 Super(ostack);
  575.                 goto chkend;
  576.             } 
  577.         } 
  578.         for (i = 0; i < 32; i++)
  579.             sendata[i] = 0;
  580.         if ((ret = mdsense(dev, 4, 0, 32, sendata)) == OK)    {
  581.             if((msiz=get3bytes(sendata+5)))    {
  582.                         delay();
  583.                         Super(ostack);
  584.                         goto chkend;
  585.             }
  586.         }
  587.         for (i = 0; i < 32; i++)
  588.             sendata[i] = 0;
  589.         if ((ret = mdsense(dev, 0, 0, 16, sendata)) == OK)    {
  590.             if((msiz=get3bytes(sendata+5)))    {
  591.                         delay();
  592.                         Super(ostack);
  593.                         goto chkend;
  594.             }
  595.         }
  596.         for (i = 0; i < 32; i++)
  597.             sendata[i] = 0;
  598.         if ((ret = mdsense(dev, 3, 0, 32, sendata)) == OK)    {
  599.             if((msiz=get3bytes(sendata+5)))    {
  600.                         delay();
  601.                         Super(ostack);
  602.                         goto chkend;
  603.             }
  604.         }
  605.         msiz = size;
  606.         delay();
  607.         Super(ostack);
  608.         goto chkerr;
  609.     }
  610.  
  611.     ostack = Super(NULL);
  612.     /* Get format parameters/ disk size from media */
  613.     set = typedev & (mask << dev);
  614.     scsidrv = typedrv & (mask << dev);
  615.     bsiz = ((set) || (scsidrv)) ? (16) : (22);
  616.     if ((set) || (scsidrv))    {
  617.         for (i = 0; i < 32; i++)
  618.             sendata[i] = 0;
  619.         mdsense(dev, 0, 0, bsiz, sendata);
  620.         if((msiz=get3bytes(sendata+5)))    {
  621.                     delay();
  622.                     Super(ostack);
  623.                     goto chkend;
  624.         }
  625. redopg:
  626.         for (i = 0; i < 32; i++)
  627.             sendata[i] = 0;
  628.         ret = mdsense(dev, page, 0, 32, sendata);/* use page code 4, but get */
  629.                                             /* info from the mdsense header */
  630.         for (i = 0; i < 32; i++)
  631.             if (sendata[i])
  632.                 break;
  633.         if ((i==32) && (page == 4))        {
  634.             page = 3;
  635.             goto redopg;
  636.         } else if (i == 32)    {
  637.             msiz = size;
  638.             delay();
  639.             Super(ostack);
  640.             goto chkend;
  641.         }
  642.         if (!(msiz = get3bytes(sendata+5)))    {
  643.             if (page == 4)    {
  644.                 page = 3;
  645.                 /*
  646.                 cyl = get3bytes(sendata+14);
  647.                 head = *(sendata+17);
  648.                 */
  649.                 goto redopg;
  650.             } else {
  651.                 /*
  652.                 spt = getword(sendata+22);
  653.                 msiz = cyl * head * spt;
  654.                 */
  655.                 msiz = size;
  656.             }
  657.         }
  658.         delay();
  659.         Super(ostack);
  660.         goto chkend;
  661.     } else    {
  662.         ret = mdsense(dev, 0, 0, 22, sendata);
  663.         delay();
  664.         Super(ostack);
  665.  
  666.         /* If full SCSI, will return number of blocks */
  667.         /* on disk at byte 5, 6 and 7.  If Adaptec,   */
  668.         /* will return 0 for number of blocks on disk */
  669.         /* on SCSI. */
  670.  
  671.             if (!(msiz = get3bytes(sendata+5))) {    /* no disk size returned? */
  672.             /* Yup, ie., it's adaptec's.  Interpret as SETMODE structure */
  673.             mb = (SETMODE *)sendata;
  674.             /* get number of cylinders */
  675.             cyl = mb->smd_cc[0];
  676.             cyl <<= 8;
  677.             cyl |= mb->smd_cc[1];
  678.     
  679.             /* get number of heads */
  680.             head = mb->smd_dhc;
  681.     
  682.             msiz = (SECTOR)head * (SECTOR)cyl * MFM;
  683.     
  684.             for (i = 0; i < 20; i++) {
  685.                 if ((ret = rdsects(dev, 1, buf, msiz+i)) == OK) {
  686.                     /* find out whether data has been transferred, by
  687.                           checking if dma pointer has been moved.      */
  688.  
  689.                     ostack = Super(NULL);
  690.                     delay();
  691.                     dmaptr = *dmahigh;
  692.                     dmaptr &= 0x0000003f;
  693.                     dmaptr <<= 16;
  694.                     tmpptr = *dmamid;
  695.                     tmpptr &= 0x000000ff;
  696.                     tmpptr <<= 8;
  697.                     dmaptr |= tmpptr;
  698.                     tmpptr = *dmalow;
  699.                     tmpptr &= 0x000000ff;
  700.                     dmaptr |= tmpptr;
  701.                     delay();
  702.                     Super(ostack);
  703.  
  704.                     if (dmaptr != buf)
  705.                         break;
  706.                    } else {            /* rdsects return an error */
  707.                     if (tsterr(ret) == OK) {
  708.                            break;
  709.                     }
  710.                 }
  711.             }
  712.     
  713.             if (ret == MDMCHGD)        /* check if error occurred */
  714.                 return (ret);
  715.        
  716.             /* Determine if media is MFM or RLL */
  717.             if (i < 20)    {
  718.                 msiz = (SECTOR)head * (SECTOR)cyl * RLL;
  719.             }
  720.             goto chkend;
  721.         }
  722.     }
  723. chkerr:
  724.     if (ret != 0) {
  725.         ret = errcode(dev);
  726.         if (tsterr(ret) != OK) 
  727.             return ERROR;
  728.         return (-3);    /* don't have to show the alert box */
  729.     }
  730. chkend:
  731.     if (size != msiz)
  732.         ret = ERROR;
  733.     else 
  734.         ret = OK;
  735.         
  736.     return (ret);
  737. }
  738.  
  739. /*
  740.  * Chkparm()
  741.  *    Check if given logical device has the asssumed parameters.
  742.  * Assumptions are:
  743.  *    - 512 bytes/sector
  744.  *    - 2 sectors/cluster
  745.  *    - 1 reserved sector
  746.  *    - 2 FATs
  747.  *
  748.  * Input:
  749.  *    ldev - logical device number ('C' -> 'P').
  750.  *
  751.  * Return:
  752.  *    OK - parameters of partition match the assumptions
  753.  *    ERROR - something went wrong.
  754.  *
  755.  * Comment:
  756.  *    Number of FATs is assumed to be 2.  Cannot check this 
  757.  * because previous version of HDX did not put that in the boot
  758.  * sector.
  759.  */
  760. chkparm(ldev)
  761. int ldev;
  762. {
  763.     char bs[512];        /* boot sector */
  764.     BOOT *boot;            /* boot structure */
  765.     UWORD bps, res, siz;    /* bytes/sector, num reserved sectors, ldev size */
  766.     int ret;
  767.  
  768.     if ((ret = rdsects(ldev, 1, bs, (SECTOR)0)) != 0) {
  769.         if (tsterr(ret) != OK)
  770.             err(bootread);
  771.         ret = ERROR;
  772.         goto parmend;
  773.     }    
  774.  
  775.     boot = (BOOT *)bs;
  776.     gw((UWORD *)&boot->b_bps, &bps);    /* what is number bytes/sector? */
  777.     gw((UWORD *)&boot->b_res, &res);    /* what is num of reserved sectors? */
  778.     gw((UWORD *)&boot->b_nsects, &siz);    /* what is size of partition */
  779.     if (bps % BPS            /* bytes per sector == ratio of 512 ? */
  780.     || res != 1) {            /* num sectors reserved == 1 ? */
  781.     ret = ERROR;            /* Nope, different from assumptions */
  782.     goto parmend;
  783.     }
  784.     
  785.     /* Check if sectors per cluster make sense */
  786.     if (boot->b_spc != 2) {
  787.         ret = ERROR;
  788.         goto parmend;
  789.     }
  790.     
  791.     ret = OK;                /* If yes, return OK */
  792.  
  793. parmend:
  794.     return ret;
  795. }
  796.  
  797.  
  798. ichkparm(ldev)
  799. int ldev;
  800. {
  801.     char bs[512];        /* boot sector */
  802.     BOOT *boot;            /* boot structure */
  803.     UWORD bps, res, siz;    /* bytes/sector, num reserved sectors, ldev size */
  804.     int ret;
  805.  
  806.     if ((ret = rdsects(ldev, 1, bs, (SECTOR)0)) != 0) {
  807.         if (tsterr(ret) != OK)
  808.             err(bootread);
  809.         ret = ERROR;
  810.         goto parmend;
  811.     }    
  812.  
  813.     boot = (BOOT *)bs;
  814.     gw((UWORD *)&boot->b_bps, &bps);    /* what is number bytes/sector? */
  815.     gw((UWORD *)&boot->b_res, &res);    /* what is num of reserved sectors? */
  816.     gw((UWORD *)&boot->b_nsects, &siz);    /* what is size of partition */
  817.     if (bps != 512            /* bytes per sector == 512 ? */
  818.     || res != 1) {            /* num sectors reserved == 1 ? */
  819.     ret = ERROR;            /* Nope, different from assumptions */
  820.     goto parmend;
  821.     }
  822.     
  823.     /* Check if sectors per cluster make sense */
  824.     if ((siz >= 0x8000L && boot->b_spc != 4) ||
  825.         (siz < 0x8000L && boot->b_spc != 2)) {
  826.         ret = ERROR;
  827.         goto parmend;
  828.     }
  829.     
  830.     ret = OK;                /* If yes, return OK */
  831.  
  832. parmend:
  833.     return ret;
  834. }
  835.  
  836.  
  837. /*
  838.  * Get dev's root block.
  839.  *
  840.  */
  841. getroot(dev, buf, sect)
  842. int dev;
  843. char *buf;
  844. SECTOR sect;
  845. {
  846.     return rdsects(dev, 1, buf, sect);
  847. }
  848.  
  849.  
  850. /*
  851.  * Put dev's root block.
  852.  *
  853.  */
  854. putroot(dev, buf, sect)
  855. int dev;
  856. char *buf;
  857. SECTOR sect;
  858. {
  859.     return wrsects(dev, 1, buf, sect);
  860. }
  861.  
  862.  
  863. /*
  864.  *  Read sector(s) from dev.
  865.  *
  866.  *  Input:
  867.  *    dev - device number (logical or physical).
  868.  *    num - number of sectors to read.
  869.  *    buf - buffer to write data read.
  870.  *    sect - starting sector number to read from.
  871.  *
  872.  *  Return:
  873.  *    errnum - 0: if read is successful.
  874.  *         an error code: if read is unsuccessful.
  875.  */
  876. rdsects(dev, num, buf, sect)
  877. int dev;            /* device number (logical or physical) */
  878. UWORD num;            /* number of sectors to read */
  879. char *buf;
  880. SECTOR sect;            /* starting sector to read from */
  881. {
  882.     int errnum;
  883.  
  884.     if (log2phys(&dev, §) < 0)
  885.     return ERROR;
  886.  
  887.     ostack = Super(NULL);
  888.     if (dev == 16)    { /* it is a AT drive */
  889.         /*
  890.         if (!(athead*atspt*sect))    {
  891.             formaterr(dev);
  892.             errnum = ERROR;
  893.         } else {
  894.             errnum = ideread(athead, atspt, sect, num, buf, (UWORD)dev);
  895.         }
  896.         */
  897.         errnum = ideread(athead, atspt, sect, num, buf, (UWORD)dev);
  898.     } else {
  899.         errnum = hread(sect, num, buf, (UWORD)dev);
  900.     }
  901.     /*
  902.     if (errnum == 04)    {      the drive is stop 
  903.         delay();
  904.         stunt();
  905.         delay();
  906.         errnum = hread(sect, num, buf, (UWORD)dev);
  907.     }
  908.     */
  909.     delay();
  910.     Super(ostack);
  911.  
  912.     if (errnum > 0) {
  913.         errnum = errcode(dev);
  914.     }
  915.         
  916.     return errnum;        /* return the error code */
  917. }
  918.  
  919.  
  920. /*
  921.  *  Write sector(s) to dev.
  922.  *
  923.  *  Input:
  924.  *    dev - device number (logical or physical).
  925.  *    num - number of sectors to write.
  926.  *    buf - buffer with data to be written.
  927.  *    sect - starting sector number to write to.
  928.  *
  929.  *  Return:
  930.  *    errnum - 0: if write is successful.
  931.  *         an error code: if write is unsuccessful.
  932.  */
  933. wrsects(dev, num, buf, sect)
  934. int dev;            /* device number (logical or physical */
  935. UWORD num;            /* number of sectors to write */
  936. char *buf;            /* buffer with data to be written */
  937. SECTOR sect;            /* starting sector to write to */
  938. {
  939.     int errnum;
  940.  
  941.     if (log2phys(&dev, §) < 0)
  942.     return ERROR;
  943.  
  944.     ostack = Super(NULL);
  945.     if (dev == 16)    { /* it is a AT drive */
  946.         /*
  947.         if (!(athead*atspt*sect))    {
  948.             formaterr(dev);
  949.             errnum = ERROR;
  950.         } else {
  951.             errnum = idewrite(athead, atspt, sect, num, buf, (UWORD)dev);
  952.         }
  953.         */
  954.         errnum = idewrite(athead, atspt, sect, num, buf, (UWORD)dev);
  955.     } else {
  956.         errnum = hwrite(sect, num, buf, (UWORD)dev);
  957.     }
  958.     delay();
  959.     Super(ostack);
  960.  
  961.     if (errnum > 0) {
  962.         errnum = errcode(dev);
  963.     }
  964.     return errnum;
  965. }
  966.  
  967.  
  968. /*
  969.  * Zero range of sectors on dev.
  970.  *
  971.  */
  972. zerosect(dev, start, count)
  973. int dev;
  974. SECTOR start;
  975. UWORD count;
  976. {
  977.     char *zbuf;
  978.     int  v;
  979.     UWORD i;
  980.  
  981.     if ((zbuf = (char *)mymalloc(ZBUFSIZ)) <= 0)
  982.         return err(nomemory);
  983.         
  984.     if (log2phys(&dev, &start) < 0) {
  985.         free(zbuf);
  986.     return ERROR;
  987.     }
  988.  
  989.     fillbuf(zbuf, (long)ZBUFSIZ, 0L);
  990.  
  991.     while (count)
  992.     {
  993.         if (count > ZCOUNT)
  994.             i = ZCOUNT;
  995.         else i = count;
  996.  
  997.     if ((v = wrsects(dev, i, zbuf, start)) != 0)
  998.         break;
  999.     start += i;
  1000.     count -= i;
  1001.     }
  1002.     free(zbuf);
  1003.     
  1004.     return v;
  1005. }
  1006.